﻿using System.Collections.Generic;
using CzfSDK;
using MySql.Data.MySqlClient;
using System.Collections;

namespace Server
{
    public static class FriendManager
    {
        /// <summary>
        /// 好友上限
        /// </summary>
        public const int MAX_FRIEND_COUNT = 50;

        public const int MAX_SINGLE_COUNT = 50;

        public const int MAX_FULL_COUNT = 100;

        public static List<Hashtable> GetSingle()
        {
            return GetTopSingle();
        }

        public static List<Hashtable> GetFull()
        {
            return GetTopFull();
        }

        /// <summary>
        /// 拉取好友列表
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        public static List<Hashtable> GetAllFriends(int userId)
        {
            return GetAll(userId);
        }

        public static List<Hashtable> GetAllApplyFriends(int userId)
        {
            return GetAllApply(userId);
        }

        /// <summary>
        /// 申请添加好友
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="friendId">好友ID</param>
        /// <returns></returns>
        public static string ApplyFriend(int userId,int friendId)
        {
            var friendUser = CheckUserCount(friendId);
            if(friendUser<=0)
                throw new CzfProtoException(Constants.ERR3, "好友不存在");
            var all = GetAllCount(userId);
            if(all>=MAX_FRIEND_COUNT)
                throw new CzfProtoException(Constants.ERR3, "好友数量达到上限");
            var all1 = GetAllCount(friendId);
            if (all1 >= MAX_FRIEND_COUNT)
                throw new CzfProtoException(Constants.ERR3, "好友数量达到上限");
            var friendCount = CheckFriendCount(userId, friendId);
            if(friendCount>0)
                throw new CzfProtoException(Constants.ERR3, "好友已经存在");
            var applyCount = CheckApplyCount(userId, friendId);
            if(applyCount>0)
                throw new CzfProtoException(Constants.ERR3, "重复申请");
            AddApply(userId, friendId);
            return "ok";
        }

        /// <summary>
        /// 删除好友
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="friendId">好友ID</param>
        /// <returns></returns>
        public static string DeleteFriend(int userId,int friendId)
        {

            return "ok";
        }

        /// <summary>
        /// 同意添加好友
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="friendId">好友ID</param>
        /// <returns></returns>
        public static string AgreeFriend(int userId, int friendId)
        {
            var friendUser = CheckUserCount(friendId);
            if (friendUser <= 0)
                throw new CzfProtoException(Constants.ERR3, "好友不存在");
            var all = GetAllCount(userId);
            if (all >= MAX_FRIEND_COUNT)
                throw new CzfProtoException(Constants.ERR3, "好友数量达到上限");
            var all1 = GetAllCount(friendId);
            if (all1 >= MAX_FRIEND_COUNT)
                throw new CzfProtoException(Constants.ERR3, "好友数量达到上限");
            var friendCount = CheckFriendCount(userId, friendId);
            if (friendCount > 0)
                throw new CzfProtoException(Constants.ERR3, "好友已经存在");
            DeleteApply(userId, friendId);
            AddFriend(userId, friendId);
            return "ok";
        }

        /// <summary>
        /// 拒绝添加好友
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="friendId">好友ID</param>
        /// <returns></returns>
        public static string RefuseFriend(int userId, int friendId)
        {
            DeleteApply(userId, friendId);
            return "ok";
        }

        #region DB
        private static int CheckFriendCount(int userId, int friendId)
        {
            var sql = "select count(*) from friend where userId=@userId and friendId=@friendId";
            return MysqlPool.current.ExecInt(sql,
                new MySqlParameter("@userId", userId),
                 new MySqlParameter("@friendId", friendId)
            );
        }

        private static int CheckApplyCount(int userId,int friendId)
        {
            var sql = "select count(*) from applyfriend where userId=@userId and friendId=@friendId";
            return MysqlPool.current.ExecInt(sql,
                new MySqlParameter("@userId", userId),
                 new MySqlParameter("@friendId", friendId)
            );
        }

        private static int CheckUserCount(int userId)
        {
            var sql = "select count(*) from user where id=@userId";
            return MysqlPool.current.ExecInt(sql,
                new MySqlParameter("@userId", userId)
            );
        }

		private static int GetAllCount(int userId)
		{
			var sql = "select count(*) from user,friend where user.id=friend.friendId and friend.userId=@userId";
			return MysqlPool.current.ExecInt(sql,
				new MySqlParameter("@userId", userId)
			);
		}

        private static List<Hashtable> GetAll(int userId)
        {
            var sql = "select * from user,friend where user.id=friend.friendId and friend.userId=@userId";
            var dt = MysqlPool.current.ExecDataTable(sql,
                new MySqlParameter("@userId", userId)
            );
            if(dt==null)  return null;
            return dt.ToList();
        }

        private static List<Hashtable> GetTopSingle()
        {
            var sql = "select * from user order by win limit @num";
            var dt = MysqlPool.current.ExecDataTable(sql,
				new MySqlParameter("@num", MAX_SINGLE_COUNT)
			);
            if (dt == null) return null;
            return dt.ToList();
        }

        private static List<Hashtable> GetTopFull()
        {
            var sql = "select * from user order by win limit @num";
            var dt = MysqlPool.current.ExecDataTable(sql,
                new MySqlParameter("@num", MAX_FULL_COUNT));
            if (dt == null) return null;
            return dt.ToList();
        }

        private static List<Hashtable> GetAllApply(int userId)
        {
            var sql = "select * from user,applyfriend where user.id=applyfriend.friendId and applyfriend.userId=@userId";
            var dt = MysqlPool.current.ExecDataTable(sql,
                new MySqlParameter("@userId", userId)
            );
            if (dt == null) return null;
            return dt.ToList();
        }

        private static int AddFriend(int userId, int friendId)
        {
            var sql = "insert into friend(userid,friendId) values(@userid, @friendId) ";
            return MysqlPool.current.ExecInt(sql,
                new MySqlParameter("@userid", userId),
                new MySqlParameter("@friendId", friendId)
            );
        }

        private static int AddApply(int userId, int friendId)
        {
            var sql = "insert into applyfriend(userid,friendId) values(@userid, @friendId) ";
            return MysqlPool.current.ExecInt(sql,
                new MySqlParameter("@userid", userId),
                new MySqlParameter("@friendId", friendId)
            );
        }

        private static int Delete(int userId, int friendId)
        {
            var sql = "delete from friend where userId=@userId and friendId=@friendId";
            return MysqlPool.current.ExecuteNonQuery(sql,
                new MySqlParameter("@userId", userId),
                new MySqlParameter("@friendId", friendId)
            );
        }

        private static int DeleteApply(int userId, int friendId)
        {
            var sql = "delete from applyfriend where userId=@userId and friendId=@friendId";
            return MysqlPool.current.ExecuteNonQuery(sql,
                new MySqlParameter("@userId", userId),
                new MySqlParameter("@friendId", friendId)
            );
        }
        #endregion
    }
}
